<?php

namespace App\Http\Services\Meeting;

use App\Http\Model\RandomMatchOnlineUserLogs;
use App\Http\Model\User;
use App\Http\Services\CommonServices;
use App\Http\Services\CommonSystemMsgServices;
use Illuminate\Support\Facades\Redis;

/**
 * 匹配-文字匹配-在线随机匹配
 */
class RandomMatchServices extends CommonServices
{
    /**
     * 缓存前缀
     *
     * @var string
     */
    private $cacheKeyPrefix = 'MEETING:ONLINE:USER:';

    /**
     * 获取缓存的key
     *
     * @param int $userId
     * @return string
     */
    private function getCacheKey(int $userId): string
    {
        return $this->cacheKeyPrefix . $userId;
    }

    /**
     * 随机匹配一个在线用户
     *
     * @param int $userId
     * @return array
     */
    public function randomMatchOneOnlineUser(int $userId)
    {
        $logModel = RandomMatchOnlineUserLogs::query()->create(['user_id' => $userId, 'day' => intval(date('Ymd'))]);
        $this->clearCache($userId);
        $result = [];
        $userModel = new User();
        $userInfo = $userModel->get_user($userId);
        $userGender = $userInfo['gender'];//性别，1=男 2=女 3=未知
        if ($userGender == 1) {
            $onlineUserIds = $userModel->getOnlineWomanArr();//在线女性用户id
        } elseif ($userGender == 2) {
            $onlineUserIds = $userModel->getOnlineManArr();//在线男性用户id
        } else {
            $onlineUserIds = $userModel->getOnlineUserArr();//在线用户id
        }

        if (!$onlineUserIds) {
            return $result;
        }

        $number = count($onlineUserIds) - 1;
        while (true) {
            $rand = rand(0, $number);//随机一个下标
            $targetUserId = $onlineUserIds[$rand];
            if ($this->checkAlreadyMatched($userId, $targetUserId)) {//已经匹配过该用户
                unset($onlineUserIds[$rand]);
                $onlineUserIds = array_values($onlineUserIds);
                $count = count($onlineUserIds);
                $number = $count - 1;
                if ($count == 0) {
                    $targetUserId = 0;
                    break;
                }
            } else {
                break;
            }
        }

        if (!$targetUserId) {
            return $result;
        }

        $targetUserInfo = $userModel->get_user($targetUserId);//目标用户信息
        if (!$targetUserInfo['nickname']) {//目标用户信息异常
            return $result;
        }

        RandomMatchOnlineUserLogs::query()->where('id', $logModel->id)->update(['target_user_id' => $targetUserId]);
        $this->setCache($userId, $targetUserId);
        $userInfo = $userModel->get_user($userId);//发起人的用户信息
        $result = ['nickname' => $userInfo['nickname'], 'user_id' => $userId,
            'user_uid' => $userInfo['user_uid'], 'image' => $userInfo['images'][0], 'gender' => $userInfo['gender']];
        (new CommonSystemMsgServices())->sendSystemMsgToUserV2($targetUserId, 80050, $result);
        $result = ['nickname' => $targetUserInfo['nickname'], 'user_id' => $targetUserId,
            'user_uid' => $targetUserInfo['user_uid'], 'image' => $targetUserInfo['images'][0], 'gender' => $targetUserInfo['gender']];
        return $result;
    }

    /**
     * 检测之前7天内是否匹配到过该用户
     *
     * @param int $userId
     * @param int $targetUserId
     * @return bool
     */
    private function checkAlreadyMatched(int $userId, int $targetUserId): bool
    {
        $cacheKey = $this->getCacheKey($userId);
        if (Redis::HEXISTS($cacheKey, $targetUserId)) {//之前匹配过
            return true;
        }

        return false;
    }

    /**
     * 将匹配到的用户放进缓存
     *
     * @param int $userId 用户id
     * @param int $targetUserId 匹配到的用户id
     * @return bool
     */
    private function setCache(int $userId, int $targetUserId): bool
    {
        $cacheKey = $this->getCacheKey($userId);
        Redis::HSET($cacheKey, $targetUserId, time() + 7 * 24 * 3600);//用户的过期时间为7天
        Redis::expire($cacheKey, 365 * 24 * 3600);//有效期一年
        return true;
    }

    /**
     * 清理过期的匹配到的并且已过期的用户
     *
     * @param int $userId
     * @return bool
     */
    private function clearCache(int $userId): bool
    {
        $cacheKey = $this->getCacheKey($userId);
        $userIdArr = Redis::HKEYS($cacheKey);
        if (empty($userIdArr)) {
            return true;
        }

        foreach ($userIdArr as $matchUserId) {
            $expiryTime = Redis::HGET($cacheKey, $matchUserId);//获得过期时间
            if ($expiryTime && time() >= $expiryTime) {
                Redis::HDEL($cacheKey, $matchUserId);//删除匹配到的用户
            }
        }

        return true;
    }
}